ShowTable of Contents
Examining LotusScript Call Stack After a Crash or Hang with NSD
There is a new feature in Notes/Domino 8.5.3 that tracks LotusScript call stacks as they execute on the client or server, and allows NSD to dump the recorded stacks. To enable this feature:
1. Place the following entry in your notes.ini:
2. Restart the Lotus Domino server or Notes client.
An Example
When enabled, an NSD dump will include a LotusScript Interpreter section like the following, which shows a stack trace for all LotusScript that was running at the time NSD was called, for all threads in all Notes/Domino processes.
To give an example, given the LotusScript code:
LotusScript Example Code
Sub Initialize
Call CountDocuments("names.nsf")
End Sub
Sub CountDocuments( dbName As String)
On Error Goto UhOh
Dim session As New NotesSession
Dim db As New NotesDatabase("", dbName)
If (Not db.IsOpen) Then
Msgbox "Database '" & dbName & "' not open'"
Exit Sub
Else
Call GetDBInfo(db)
End If
Exit Sub
UhOh:
Msgbox "Error '" & Error$ & "' at line " & Erl
Exit Sub
End Sub
Sub GetDBInfo(db As NotesDatabase)
Dim docCount As Integer
Dim viewCount As Integer
Dim formsCount As Integer
docCount = CountDocs(db)
viewCount = CountViews(db)
formsCount = CountForms(db)
Msgbox "Database '" & db.FileName & "' has " & docCount & " documents, " & viewCount & " views and " & formsCount & " forms"
End Sub
Function CountDocs(db As notesdatabase) As Integer
CountDocs = db.AllDocuments.Count
End Function
Function CountViews(db As NotesDatabase) As Integer
CountViews = Ubound(db.View) ' Let's say Notes crashes here, for example
End Function
Function CountForms(db As NotesDatabase) As Integer
CountForms = Ubound(db.Forms)
End Function
When the memcheck portion of NSD is run, a section will appear in the output for each process executing LotusScript code, listing each stack on a per thread basis. This could mean that there are LotusScript stacks for Amgr, HTTP, router, server or nlnotes, depending on how LotusScript code is being executed.
Matching the fatal thread's process and thread ID (in this example 0ef8 and 1494) will reveal the following LotusScript call stack:
C Call Stack
############################################################
### FATAL THREAD 1/12 [ nlnotes: 0ef8: 1494]
### FP=0x00137020, PC=0x0235582a, SP=0x00136fdc
### stkbase=00140000, total stksize=327680, used stksize=36900
### EAX=0x00000000, EBX=0x10b13e6c, ECX=0x000001bf, EDX=0x0000001e
### ESI=0x10b13b20, EDI=0x10b13e6c, CS=0x0000001b, SS=0x00000023
### DS=0x00000023, ES=0x00000023, FS=0x0000003b, GS=0x00000000 Flags=0x00010246
Exception code: c0000005 (ACCESS_VIOLATION)
############################################################
@[ 1] 0x0235582a nnotes.LSsThread::Do_OP_LSI+2874 (10b13b20,1bf,10b13e5c,10b13b20) @lsthopc3.cpp(640)
@[ 2] 0x02355b27 nnotes.LSsThread::OP_LSI+39 (10b13b20,1,2,10b13b20) @lsthopc3.cpp(659)
@[ 3] 0x0232836a nnotes.LSsThread::NRun+6282 (10b13b20,10aeb508,10b13b20,137138) @lsthrun.cpp(1745)
@[ 4] 0x02328986 nnotes.LSsThread::Run+198 (10b13b20,10aeb508,429bd00,4) @lsthrun.cpp(1874)
@[ 5] 0x0231ae29 nnotes.LSsThread::ExecuteProc+313 (10b13b20,10aeb508,4,0) @lsthread.cpp(537)
@[ 6] 0x02346455 nnotes.LSsInstance::Run+533 (429bd00,10aeb508,4,0) @apiinst.cpp(605)
...
LotusScript Call Stack
<@@ ------ LotusScript Interpreter -> Call Stack for [ nlnotes: 0ef8: 1494] (Time 10:38:14) ------ @@>
[3] COUNTVIEWS
[2] GETDBINFO @ line number 7
[1] COUNTDOCUMENTS @ line number 12
[0] INITIALIZE @ line number 2
The LotusScript stack can be read as follows:
- Sub Initialize was at line 2, which called CountDocuments
- Sub CountDocuments was at line 12 when it called GetDbInfo
- Sub GetDbInfo called CountViews from line 7
- There was a crash in CountViews
Other Details
Note that all symbols appear in all upper case.
Line numbers are relative to the section in the Designer in which the code is defined.
The following calls will appear in the call stack:
- User-defined LotusScript subs
- User-defined LotusScript functions
- User-defined LotusScript class methods
- LotusScript properties
- Event Handlers
- ADT Methods
- ADT Properties
- C-Callouts
Note: LotusScript built-in functions such as Instr(), Ubound(), etc, do not appear in the call stack
Also Note: Hidden design elements will appear in a LotusScript stack dump
If DEBUG_LS_DUMP is not set, then there is no overhead associated with this feature. However, if it is set, then there will be a performance penalty of approximately 3%-6%, and a 32K memory penalty per LotusScript thread running. There is enough space allocated per thread for a stack approximately 200 calls deep. It is also important to note that if nsd is executed with any options that cause memcheck to not execute, such as -stacks or -nomemcheck, then LotusScript call stacks will not appear in the resulting output.
Note: Even though the run-time overhead for LSD4NSD is low, it should not be enabled long-term on a Notes Client or Domino Server. Enable it only as long as you need it, then disable it